from flask.blueprints import Blueprint
from flask import Flask
import pika
from pika import channel
from config import config
from redis import StrictRedis
from pika import PlainCredentials
from pika.connection import Connection
from flask_cors import CORS
from flask_caching import Cache
from concurrent.futures import ThreadPoolExecutor

# redis缓存
redis_client: StrictRedis = None

# RabbitMQ的链接认证
auth: PlainCredentials = None
connet_parameter: pika.ConnectionParameters = None

# 配置跨域
cors = CORS()

# 线程池
executor = None

# 请求缓存
cache = None


def create_app(config_name: str) -> Flask:
    # 读取配置信息
    app = Flask(__name__)
    app.config.from_object(config[config_name])
    config[config_name].init_app(app)

    # 配置响应缓存
    global cache
    cache = Cache(config={
        'CACHE_TYPE': 'RedisCache',
        'CACHE_REDIS_HOST': app.config['REDIS_HOST'],
        'CACHE_REDIS_PORT': app.config['REDIS_PORT']
    })
    cache.init_app(app)

    #  进行一些初始化操作
    # 0. 配置跨域
    cors.init_app(app, resources={
        '/api/*': {'origins': '*'}
    })

    # 1. 初始化Redis
    global redis_client
    redis_client = StrictRedis(host=app.config['REDIS_HOST'],
                               port=app.config['REDIS_PORT'])

    # 2. 初始化RabbitMQ
    global auth
    global connection
    global connet_parameter
    
    auth = PlainCredentials(username=app.config['RABBIT_USERNAME'],
                            password=app.config['RABBIT_PASSWORD'])

    connet_parameter = pika.ConnectionParameters(host=app.config['RABBIT_HOST'],
                                  port=app.config['RABBIT_PORT'],
                                  virtual_host=app.config['VIRTUAL_HOST'],
                                  credentials=auth)
    # 3. 配置线程池
    global executor
    executor = ThreadPoolExecutor(10)
    # connection = pika.BlockingConnection(connet_parameter)
    # channel = connection.channel()
    # with open('./tests/base64.txt', 'r') as f:
    #     txt = f.read()
    # txt = re.sub('^data:image/.+;base64,', '', txt)
    # channel.basic_publish(exchange='pytools.system.direct',
    #                       routing_key='email',
    #                       body=txt)
    # print(channel)

    # 导入不同的蓝图
    from .api import api as api_blueprint
    app.register_blueprint(api_blueprint, url_prefix='/api')  # 导入接口

    # 工厂生产app
    return app
